package org.tokaf.rater;

import org.tokaf.TopKElement;
import org.tokaf.datasearcher.DataSearcher;

/**
 * <p>EuclidRater computes euclid distance of the point represented by ratings
 * of attributes from the point [1,1,...].</p> <p>Copyright (c) 2006</p>
 * @author Alan Eckhardt
 * @version 1.0
 */
public class EuclidRater extends Rater {
	public EuclidRater(String fields[]) {
		this.fields = (String[]) fields.clone();
	}

	public double getDerivation(int index, DataSearcher[] data, TopKElement el) {
		double first = 0;
		// Computes the distance of given point el from point 1,1,...
		for (int i = 0; i < el.getLength(); i++) {
			if (el.isNull(i)) {
				first += 1 - 0 * 0;
			} else {
				double temp = el.getRating(i);
				first += 1 - temp * temp;
			}
		}
		// Maximal distance from point 1,1,1, is Sqrt(1+1+1+...).
		// Number of 1 is equal to dimension of space
		// We must divide by this maximal distance to get interval 0,1
		first = 1 - (Math.sqrt(first) / Math.sqrt(el.getLength()));
		double second = el.getRating(index);
		return first * second;
	}

	public double getRating(TopKElement el, DataSearcher[] data, double optional) {
		double a = 0;
		// Computes the distance of given point el from point 1,1,...
		for (int i = 0; i < el.getLength(); i++) {
			if (el.isNull(i)) {
				a += 1 - optional * optional;
			} else {
				double temp = el.getRating(i);
				a += 1 - temp * temp;
			}
		}
		// Maximal distance from point 1,1,1, is Sqrt(1+1+1+...).
		// Number of 1s is equal to dimension of space
		// We must divide by this maximal distance to get interval 0,1
		return 1 - (Math.sqrt(a) / Math.sqrt(el.getLength()));
	}

	public double getRating(TopKElement el, DataSearcher[] data,
			TopKElement optional) {
		double a = 0;
		// Computes the distance of given point el from point 1,1,...
		for (int i = 0; i < el.getLength(); i++) {
			if (el.isNull(i)) {
				double temp = optional.getRating(i);
				a += 1 - temp * temp;
			} else {
				double temp = el.getRating(i);
				a += 1 - temp * temp;
			}
		}
		// Maximal distance from point 1,1,1, is Sqrt(1+1+1+...).
		// Number of 1 is equal to dimension of space
		// We must divide by this maximal distance to get interval 0,1
		return 1 - (Math.sqrt(a) / Math.sqrt(el.getLength()));
	}

}
